﻿# -*-coding: UTF-8 -*-
import logging
import time

from PyQt5.QtCore import QTimer, Qt
from PyQt5.QtWidgets import QApplication

from Clover.CloverEngine import CloverEngine
from CloverWindow.SplashWindow.SplashWindow import SplashWindow


class CloverApplication(QApplication):
	def __init__(self, argv):
		super().__init__(argv)
		self.engine = None
		self.launcher = None
		self.main_loop = QTimer()
		self.main_loop.timeout.connect(self.game_loop)
		self.last_frame_time = 0
		self.logger = logging.getLogger("CloverApplication")
		self.splash_window = None

	def start_application(self, engine: CloverEngine):
		self.engine = engine
		self.logger.info(f"initialize main loop for {self.engine}")
		"""启动引擎循环定时器"""
		self.main_loop.start(1)  # 1ms 间隔
		"""设置定时器类型为精确计时器"""
		self.main_loop.setTimerType(Qt.PreciseTimer)
		"""启动Splash异步初始化引擎"""
		self.logger.info(f"start launch {self.engine}")
		self.engine.start()
		from CloverLauncher.Launcher import Launcher
		self.launcher = Launcher()
		self.launcher.start(self.on_engine_launch_start, self.on_engine_launch_finish)

	def on_engine_launch_start(self):
		# 创建并显示splash window，传入进度回调函数
		self.splash_window = SplashWindow()
		self.splash_window.show()
		self.splash_window.raise_()
		self.splash_window.start_splash(self.launcher.get_launch_progress, self.get_launch_progress_name)

	def get_launch_progress(self):
		return self.launcher.get_launch_progress

	def get_launch_progress_name(self):
		return self.launcher.get_launch_progress_description()

	def on_engine_launch_finish(self):
		# 完成时关闭splash
		if self.splash_window:
			# 延迟关闭splash，让用户看到完成状态
			self.splash_window.stop_splash()
			QTimer.singleShot(800, self.splash_window.close_splash)
		self.logger.info(f"finish launch <{self.engine}>")

	def game_loop(self):
		if not self.engine:
			return
		current_time = time.perf_counter()
		delta_time = current_time - self.last_frame_time
		# 动态获取当前帧率设置
		frame_duration = 1 / self.engine.get_frame_rate()

		if delta_time >= frame_duration:
			# 记录帧开始时间
			frame_start_time = time.perf_counter()
			self.engine.pre_tick(frame_start_time)
			self.engine.tick(delta_time)
			self.engine.post_tick(current_time, time.perf_counter() - frame_start_time)
			self.last_frame_time = current_time

	def request_exit(self):
		"""请求退出应用程序"""
		self.main_loop.stop()
		if self.engine:
			self.engine.destroy()
			self.engine = None
		self.quit()

	def is_running(self):
		return self.main_loop.isActive()
